﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Management;
using System.Net.NetworkInformation;
using System.Security.Principal;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace iSet
{
    public partial class IPSet : Form
    {
        #region Attributes

        private string SettingNameSelectValue = "0";
        private string SettingListSelectValue = "0";
        private string NetCardListSelectValue = "";

        private int SmallWidth = 0;
        private int BigWidth = 0;

        private bool IsOpen = false;

        QT.Windows.SafeTokenHandle pToken;

        #endregion

        #region Form

        public IPSet()
        {
            InitializeComponent();
        }

        private void IPSet_Load(object sender, EventArgs e)
        {
            SmallWidth = SystemInformation.BorderSize.Width * 2 + SystemInformation.Border3DSize.Width * 2 + this.gbMain.Location.X * 2 + gbMain.Width;
            BigWidth = SystemInformation.BorderSize.Width * 2 + SystemInformation.Border3DSize.Width * 2 + this.gbMain.Location.X + this.gbIP.Location.X + this.gbIP.Width;
            this.Width = SmallWidth;

            ReleaseFile();
            CheckUser();

            InitForm();
            InitToolStripMenuItem();
        }

        private void IPSet_Shown(object sender, EventArgs e)
        {
            this.notifyIcon.Visible = true;
            this.WindowState = FormWindowState.Minimized;
            this.Hide();
        }

        private void IPSet_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.notifyIcon.Visible = true;
                this.Hide();
            }
        }

        /// <summary>
        /// 初始化Form
        /// </summary>
        private void InitForm()
        {
            //初始化网卡列表
            InitCardList();

            //初始化配置列表
            InitSettingList();

            #region 根据选中网卡初始化IP配置列表选中项

            this.cbbSettingList.SelectedValue = DB.GetSettingID(this.cbbNetCardList.SelectedValue.ToString());

            #endregion
        }

        #endregion

        #region ComboBox

        #region Initialization

        /// <summary>
        /// 初始化网卡列表
        /// </summary>
        private void InitCardList()
        {
            DataTable dt = DB.GetNetCardList();
            this.cbbNetCardList.ValueMember = dt.Columns[0].ToString();
            this.cbbNetCardList.DisplayMember = dt.Columns[1].ToString();
            this.cbbNetCardList.DataSource = dt;
        }

        /// <summary>
        /// 初始化配置列表
        /// </summary>
        private void InitSettingList()
        {
            DataTable dt = DB.GetSettingList();
            if (DB.GetSettingID(NetCardListSelectValue) == "0")
            {
                DataRow dr = dt.NewRow();
                dr["id"] = "0";
                dr["SettingName"] = "未配置";
                dt.Rows.InsertAt(dr, 0);
            }
            this.cbbSettingList.ValueMember = dt.Columns[0].ToString();
            this.cbbSettingList.DisplayMember = dt.Columns[1].ToString();
            this.cbbSettingList.DataSource = dt;
        }

        /// <summary>
        /// 初始化配置列表（设置）
        /// </summary>
        private void InitSettingName()
        {
            DataTable dt = DB.GetSettingList();
            this.cbbSettingName.ValueMember = dt.Columns[0].ToString();
            this.cbbSettingName.DisplayMember = dt.Columns[1].ToString();
            this.cbbSettingName.DataSource = dt;
        }

        #endregion

        #region SelectedIndexChanged

        private void cbbNetCardList_SelectedIndexChanged(object sender, EventArgs e)
        {
            NetCardListSelectValue = this.cbbNetCardList.SelectedValue.ToString();
            InitSettingList();
            this.cbbSettingList.SelectedValue = DB.GetSettingID(NetCardListSelectValue);
        }

        private void cbbSettingList_SelectedIndexChanged(object sender, EventArgs e)
        {
            SettingListSelectValue = this.cbbSettingList.SelectedValue.ToString();

            DataTable dt = DB.GetIPSetting(SettingListSelectValue);

            if (dt.Rows.Count == 1)
            {
                this.lblIP.Text = dt.Rows[0]["isdhcp"].ToString().ToLower() == "true" ? "自动获取" : dt.Rows[0]["ip"].ToString();
                this.lblMask.Text = dt.Rows[0]["isdhcp"].ToString().ToLower() == "true" ? "自动获取" : dt.Rows[0]["mask"].ToString();
                this.lblGateWay.Text = dt.Rows[0]["isdhcp"].ToString().ToLower() == "true" ? "自动获取" : dt.Rows[0]["gateway"].ToString();
                this.lblPrimaryDns.Text = dt.Rows[0]["autodns"].ToString().ToLower() == "true" ? "自动获取" : dt.Rows[0]["dns1"].ToString();
                this.lblSecondaryDns.Text = dt.Rows[0]["autodns"].ToString().ToLower() == "true" ? "" : dt.Rows[0]["dns2"].ToString();
            }
            else
            {
                this.lblIP.Text = "";
                this.lblMask.Text = "";
                this.lblGateWay.Text = "";
                this.lblPrimaryDns.Text = "";
                this.lblSecondaryDns.Text = "";
            }

            CompareIP();
        }

        private void cbbSettingName_SelectedIndexChanged(object sender, EventArgs e)
        {
            SettingNameSelectValue = this.cbbSettingName.SelectedValue.ToString();

            DataTable dt = DB.GetIPSetting(SettingNameSelectValue);

            if (dt.Rows.Count == 1)
            {
                if (dt.Rows[0]["isdhcp"].ToString().ToLower() == "true") this.cbIP.Checked = true;
                else this.cbIP.Checked = false;
                if (dt.Rows[0]["autodns"].ToString().ToLower() == "true") this.cbDns.Checked = true;
                else this.cbDns.Checked = false;
                this.tbIP.Text = dt.Rows[0]["ip"].ToString();
                this.tbMask.Text = dt.Rows[0]["mask"].ToString();
                this.tbGateWay.Text = dt.Rows[0]["gateway"].ToString();
                this.tbPrimaryDns.Text = dt.Rows[0]["dns1"].ToString();
                this.tbSecondaryDns.Text = dt.Rows[0]["dns2"].ToString();
            }
            else
            {
                this.cbIP.Checked = false;
                this.cbDns.Checked = false;
                this.tbIP.Text = "";
                this.tbMask.Text = "";
                this.tbGateWay.Text = "";
                this.tbPrimaryDns.Text = "";
                this.tbSecondaryDns.Text = "";
            }
        }

        #endregion

        #endregion

        #region Button

        /// <summary>
        /// 设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetting_Click(object sender, EventArgs e)
        {
            InitSettingName();

            if (SettingListSelectValue != "0") this.cbbSettingName.SelectedValue = SettingListSelectValue;

            if (IsOpen == false)
            {
                IsOpen = true;
                this.Width = BigWidth;
                this.btnSetting.Text = "完成";
            }
            else
            {
                IsOpen = false;
                this.Width = SmallWidth;
                this.btnSetting.Text = "配置";
            }
        }

        /// <summary>
        /// 应用设置到网卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnApply_Click(object sender, EventArgs e)
        {
            GlobalAttrib.Nid = this.cbbNetCardList.SelectedValue.ToString();
            GlobalAttrib.Sid = this.cbbSettingList.SelectedValue.ToString();

            Setting Setting = new Setting();
            Setting.ShowDialog();
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            #region 验证数据合法性

            if (this.tbIP.Text.Length == 0)
            {
                MessageBox.Show("请输入IP地址");
                this.tbIP.Focus();
                return;
            }
            if (!QT.Net.NetWork.CheckIP(this.tbIP.Text))
            {
                MessageBox.Show("请输入正确的IP地址");
                this.tbIP.SelectAll();
                this.tbIP.Focus();
                return;
            }
            if (this.tbMask.Text.Length == 0)
            {
                MessageBox.Show("请输入子网掩码");
                this.tbMask.Focus();
                return;
            }
            if (!QT.Net.NetWork.CheckMask(this.tbMask.Text))
            {
                MessageBox.Show("请输入正确的子网掩码");
                this.tbMask.SelectAll();
                this.tbMask.Focus();
                return;
            }
            if (this.tbGateWay.Text.Length > 0)
            {
                if (!QT.Net.NetWork.CheckIP(this.tbGateWay.Text))
                {
                    MessageBox.Show("请输入正确的网关");
                    this.tbGateWay.SelectAll();
                    this.tbGateWay.Focus();
                    return;
                }
                if ((QT.Net.IP.IPToLong(this.tbIP.Text) & QT.Net.IP.IPToLong(this.tbMask.Text)) != (QT.Net.IP.IPToLong(this.tbGateWay.Text) & QT.Net.IP.IPToLong(this.tbMask.Text)))
                {
                    if (MessageBox.Show("IP地址和网关不在同一网段,确认要设置吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                    {
                        return;
                    }
                }
            }            
            if (this.tbPrimaryDns.Text.Length>0&&(!QT.Net.NetWork.CheckIP(this.tbPrimaryDns.Text)))
            {
                MessageBox.Show("请输入正确的DNS");
                this.tbPrimaryDns.SelectAll();
                this.tbPrimaryDns.Focus();
                return;
            }
            if (this.tbSecondaryDns.Text.Length > 0 && (!QT.Net.NetWork.CheckIP(this.tbSecondaryDns.Text)))
            {
                MessageBox.Show("请输入正确的DNS");
                this.tbSecondaryDns.SelectAll();
                this.tbSecondaryDns.Focus();
                return;
            }

            #endregion

            #region 保存IP记录

            //判断配置是否存在
            string sid;
            if (string.IsNullOrEmpty(SettingNameSelectValue)) sid = "0";
            else sid = SettingNameSelectValue;
            if (DB.CheckIPSettingName(this.cbbSettingName.Text, sid)) 
            {
                MessageBox.Show("配置名称\"" + this.cbbSettingName.Text + "\"已存在");
                return ;
            }
            
            string SelectedValue = SettingListSelectValue;

            if (sid == "0")
            {
                if (DB.AddIPSetting(this.cbbSettingName.Text, this.cbIP.Checked, this.tbIP.Text, this.tbMask.Text, this.tbGateWay.Text, this.cbDns.Checked, this.tbPrimaryDns.Text,this.tbSecondaryDns.Text) == true)
                {
                    MessageBox.Show("保存成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                }

                InitSettingList();
                this.cbbSettingList.SelectedValue = SelectedValue;
            }
            else
            {
                if (DB.UpdateIPSetting(SettingNameSelectValue, this.cbbSettingName.Text, this.cbIP.Checked, this.tbIP.Text, this.tbMask.Text, this.tbGateWay.Text, this.cbDns.Checked, this.tbPrimaryDns.Text , this.tbSecondaryDns.Text) == true)
                {
                    MessageBox.Show("修改成功");
                }
                else
                {
                    MessageBox.Show("操作失败");
                }
            }

            #endregion

            InitSettingList();
            this.cbbSettingList.SelectedValue = SelectedValue;
            InitToolStripMenuItem();
        }

        #endregion

        #region IPMethod

        #region CheckedChanged

        private void cbIP_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbIP.Checked)
            {
                this.gbIP.Enabled = false;
                this.cbDns.Enabled = true;
                this.cbDns.Checked = true;
            }
            else
            {
                this.gbIP.Enabled = true;
                this.cbDns.Checked = false;
                this.cbDns.Enabled = false;
            }
        }

        private void cbDns_CheckedChanged(object sender, EventArgs e)
        {
            if (this.cbIP.Checked == false) this.cbDns.Checked = false;

            if (this.cbDns.Checked)
            {
                this.gbDns.Enabled = false;
            }
            else
            {
                this.gbDns.Enabled = true;
            }
        }

        #endregion

        #region Button

        /// <summary>
        /// 新增配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, EventArgs e)
        {
            int count = this.cbbSettingName.Items.Count;
            DataTable dt = DB.GetSettingList();
            DataRow dr = dt.NewRow();
            dr["id"] = "0";
            dr["SettingName"] = "配置" + count.ToString();
            dt.Rows.InsertAt(dr, 0);
            this.cbbSettingName.ValueMember = dt.Columns[0].ToString();
            this.cbbSettingName.DisplayMember = dt.Columns[1].ToString();
            this.cbbSettingName.DataSource = dt;
            this.cbbSettingName.SelectedValue = 0;
        }

        /// <summary>
        /// 删除配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDel_Click(object sender, EventArgs e)
        {
            if (this.cbbSettingName.Items.Count == 0) return;

            int index = this.cbbSettingName.SelectedIndex;
            if (this.cbbSettingName.Items.Count == 1)
            {
                MessageBox.Show("您至少要有一条配置");
                return;
            }
            if (DB.DeleteIPSetting(this.cbbSettingName.SelectedValue.ToString()))
            {
                string SelectedValue = this.cbbSettingList.SelectedValue.ToString();
                InitSettingName();
                InitSettingList();
                if (index >= this.cbbSettingName.Items.Count)
                {
                    this.cbbSettingName.SelectedIndex = index - 1;
                }
                else
                {
                    this.cbbSettingName.SelectedIndex = index;
                }
                try
                {
                    this.cbbSettingList.SelectedValue = SelectedValue;
                }
                catch
                {
                    cbbNetCardList_SelectedIndexChanged(sender, e);
                }
            }
            else
            {
                MessageBox.Show("操作失败");
            }
        }

        #endregion

        #region GetLocalIP

        private void CompareIP()
        {
            RegistryKey regKey = Registry.LocalMachine;
            string SubKeyPath = @"SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces";
            RegistryKey optionKey = regKey.OpenSubKey(SubKeyPath, true);
            if (optionKey == null)
            {
                MessageBox.Show(@"注册表损坏，请修复\nHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces");
                return;
            }

            string[] Adapters = optionKey.GetSubKeyNames();
            foreach (string Adapter in Adapters)
            {
                if (Adapter.ToUpper() == NetCardListSelectValue.ToUpper())
                {
                    RegistryKey AdapterKey = optionKey.OpenSubKey(Adapter, true);
                    if (AdapterKey.GetValue("EnableDHCP").ToString() == "1")
                    {
                        //自动获取IP
                        if (this.lblIP.Text != "自动获取") this.lblIP.ForeColor = System.Drawing.Color.Red;
                        else this.lblIP.ForeColor = System.Drawing.SystemColors.ControlText;
                        if (this.lblMask.Text != "自动获取") this.lblMask.ForeColor = System.Drawing.Color.Red;
                        else this.lblMask.ForeColor = System.Drawing.SystemColors.ControlText;
                        if (this.lblGateWay.Text != "自动获取") this.lblGateWay.ForeColor = System.Drawing.Color.Red;
                        else this.lblGateWay.ForeColor = System.Drawing.SystemColors.ControlText;

                    }
                    else
                    {
                        if (AdapterKey.GetValue("IPAddress").ToString() != this.lblIP.Text) this.lblIP.ForeColor = System.Drawing.Color.Red;
                        else this.lblIP.ForeColor = System.Drawing.SystemColors.ControlText;
                        if (AdapterKey.GetValue("SubnetMask").ToString() != this.lblMask.Text) this.lblMask.ForeColor = System.Drawing.Color.Red;
                        else this.lblMask.ForeColor = System.Drawing.SystemColors.ControlText;
                        if (AdapterKey.GetValue("DefaultGateway").ToString() != this.lblGateWay.Text) this.lblGateWay.ForeColor = System.Drawing.Color.Red;
                        else this.lblGateWay.ForeColor = System.Drawing.SystemColors.ControlText;
                    }

                    if (AdapterKey.GetValue("EnableDHCP").ToString() == "1" && string.IsNullOrEmpty(AdapterKey.GetValue("NameServer").ToString()))
                    {
                        //自动获取DNS
                        if (this.lblPrimaryDns.Text != "自动获取") this.lblPrimaryDns.ForeColor = System.Drawing.Color.Red;
                        else this.lblPrimaryDns.ForeColor = System.Drawing.SystemColors.ControlText;
                    }
                    else
                    {
                        if ((!AdapterKey.GetValue("NameServer").ToString().Contains(this.lblPrimaryDns.Text)) && (!AdapterKey.GetValue("NameServer").ToString().Contains(this.lblSecondaryDns.Text)))
                        {
                            this.lblPrimaryDns.ForeColor = System.Drawing.Color.Red;
                            this.lblSecondaryDns.ForeColor = System.Drawing.Color.Red;
                        }
                        else
                        {
                            this.lblPrimaryDns.ForeColor = System.Drawing.SystemColors.ControlText;
                            this.lblSecondaryDns.ForeColor = System.Drawing.SystemColors.ControlText;
                        }
                    }
                }
            }
        }

        #endregion

        #endregion

        #region ReleaseFile

        private void ReleaseFile()
        {
            string dbFile = @".\iSet.db";
            if (!File.Exists(dbFile))
            {
                byte[] buffer = Properties.Resources.iSet;//这个是添加EXE到程序资源时的名称
                FileStream FS = new FileStream(dbFile, FileMode.Create);//新建文件
                BinaryWriter BWriter = new BinaryWriter(FS);//以二进制打开文件流
                BWriter.Write(buffer, 0, buffer.Length);//从资源文件读取文件内容，写入到一个文件中
                BWriter.Close();
                FS.Close();
            }
        }

        #endregion

        #region CheckUser

        private void CheckUser()
        {
            if (!QT.Windows.WinLogon.IsAdministrators())
            {
                DataTable dt = DB.GetUser();

                if (dt.Rows.Count == 0 || !QT.Windows.WinLogon.Logon(dt.Rows[0]["username"].ToString(), QT.Security.AESHelper.AESDecrypt(dt.Rows[0]["pass"].ToString()), out pToken))
                {
                    Login Login = new Login();
                    Login.ShowDialog();
                }
                else
                {
                    if (System.Environment.OSVersion.Version.Major >= 6)
                    {
                        QT.Windows.WinLogon.CreateProcess(dt.Rows[0]["username"].ToString(), QT.Security.AESHelper.AESDecrypt(dt.Rows[0]["pass"].ToString()), Application.StartupPath, Application.ExecutablePath, Process.GetCurrentProcess().ProcessName);
                        Application.Exit();
                    }
                    using (pToken)
                    {
                        using(WindowsIdentity.Impersonate(pToken.DangerousGetHandle()))
                        {
                        if (!QT.Windows.WinLogon.IsAdministrators())
                        {
                            Login Login = new Login();
                            Login.ShowDialog();
                        }
                        }
                    }
                }
            }
        }

        #endregion

        #region TextBox

        private void tbMask_Enter(object sender, EventArgs e)
        {
            if (!QT.Net.NetWork.CheckIP(this.tbIP.Text))
            {
                MessageBox.Show("请输入合法的IP地址");
                this.tbIP.SelectAll();
                this.tbIP.Focus();
                return;
            }
            
            if(this.tbMask.Text.Length==0)
            {
                switch (QT.Net.IP.IPType(this.tbIP.Text))
                {
                    case "A":
                        this.tbMask.Text = "255.0.0.0";
                        break;
                    case "B":
                        this.tbMask.Text = "255.255.0.0";
                        break;
                    case "C":
                        this.tbMask.Text = "255.255.255.0";
                        break;
                    case "LOCAL":
                        MessageBox.Show("本机回环地址不能做为IP");
                        this.tbIP.Focus();
                        this.tbIP.SelectAll();
                        return;
                    case "DHCP":
                        MessageBox.Show("系统保留地址不能做为IP");
                        this.tbIP.Focus();
                        this.tbIP.SelectAll();
                        return;
                    default:
                        MessageBox.Show("IANA保留地址不能做为IP");
                        this.tbIP.Focus();
                        this.tbIP.SelectAll();
                        return;
                }
            }
        }

        #endregion

        #region ToolStripMenuItem

        private void InitToolStripMenuItem()
        {
            ToolStripMenuItem itemStart = (ToolStripMenuItem)this.contextMenuStrip.Items[0];
            ToolStripMenuItem itemEnd = (ToolStripMenuItem)this.contextMenuStrip.Items[this.contextMenuStrip.Items.Count - 1];

            this.contextMenuStrip.Items.Clear();
            this.contextMenuStrip.Items.Add(itemStart);

            DataTable dt = DB.GetNetCardList();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                int Index = this.contextMenuStrip.Items.Count - 2;
                ToolStripMenuItem item = new ToolStripMenuItem(dt.Rows[i]["Des"].ToString(),null,null,dt.Rows[i]["Nid"].ToString());
                this.contextMenuStrip.Items.Add(item);
                DataTable IPSetting = DB.GetSettingList();
                string Sid = DB.GetSettingID(dt.Rows[i]["Nid"].ToString());
                for (int j = 0; j < IPSetting.Rows.Count; j++)
                {
                    ToolStripMenuItem subitem;
                    if (IPSetting.Rows[j]["id"].ToString() == Sid)
                    {
                        subitem = new ToolStripMenuItem(IPSetting.Rows[j]["SettingName"].ToString(), Properties.Resources.right, ToolStripMenuItemApply, IPSetting.Rows[j]["id"].ToString());
                    }
                    else
                    {
                        subitem = new ToolStripMenuItem(IPSetting.Rows[j]["SettingName"].ToString(), null, ToolStripMenuItemApply, IPSetting.Rows[j]["id"].ToString());
                    }
                    item.DropDownItems.Add(subitem);
                }
            }

            this.contextMenuStrip.Items.Add(itemEnd);
        }

        private void ToolStripMenuItem_Main_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Normal && this.Visible == true)
            {
                this.WindowState = FormWindowState.Minimized;
                this.Hide();
                this.ToolStripMenuItem_Main.Text = "显示主界面";
            }
            else
            {
                this.Visible = true;
                this.WindowState = FormWindowState.Normal;
                this.ToolStripMenuItem_Main.Text = "隐藏主界面";
            }
        }

        private void ToolStripMenuItem_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void ToolStripMenuItemApply(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            GlobalAttrib.Nid = item.OwnerItem.Name;
            GlobalAttrib.Sid = item.Name;

            Setting Setting = new Setting();
            Setting.ShowDialog();

            InitToolStripMenuItem();
        }

        #endregion
    }
}
